﻿#ifndef MYPLOTFRAME_H
#define MYPLOTFRAME_H

#include <QWidget>
#include <QMap>
#include "qcustomplot.h"

#define yAxisLen   130   // 纵坐标 最大速度
#define xAxisLen   15000 // 横坐标 时间
#define scMaxPoint 50000 // 画图最大点数

enum CurveTypeEnum : int
{
    /// <summary>
    /// 速度曲线
    /// </summary>
    SpeedC = 0,
    /// <summary>
    /// 涡流扭力和曲线
    /// </summary>
    ForceSumC,
    /// <summary>
    /// 左前涡流扭力曲线
    /// </summary>
    ForceL0C,
    /// <summary>
    /// 右前涡流扭力曲线
    /// </summary>
    ForceR0C,
    /// <summary>
    /// 左后涡流扭力曲线
    /// </summary>
    ForceL1C,
    /// <summary>
    /// 右后涡流扭力曲线
    /// </summary>
    ForceR1C,
    /// <summary>
    /// 功率曲线
    /// </summary>
    PowerC,
    /// <summary>
    /// 输出电压曲线
    /// </summary>
    OutVC,
    /// <summary>
    /// 目标扭力曲线
    /// </summary>
    DesForceC,
    /// <summary>
    /// 控制断点曲线
    /// </summary>
    BkPointC,
    /// <summary>
    /// 加速度曲线
    /// </summary>
    JSDC,
    /// <summary>
    /// 枚举结束，必须放在最后
    /// </summary>
    EndC
};

typedef struct _SamplingDataItem
{
    qreal  Speed;              // 速度 单位km/h
    qreal  AddSpeed;           // 加速度
    qint32 BeforeForceL;       // 前左涡流扭力
    qint32 BeforeForceR;       // 前右涡流扭力
    qint32 AfterForceL;        // 后左涡流扭力
    qint32 AfterForceR;        // 后右涡流扭力
    qint32 ForceSum;           // 扭力和值
    qreal  Power;              // 涡流功率
    qint32 Mileage;            // 里程数 单位m
    qint32 BkPoint;            // PID控制断点
    qint32 CtrlType;           // 控制方式
    qreal  OutDesV;            // 采集板方式 输出目标电压
    qreal  CtrlDes;            // 控制目标
    qint32 SampPointNo;        // 采集点序号
    qint64 Timestamp;          // 时间戳
    _SamplingDataItem()
        : Speed(0.0), AddSpeed(0.0), BeforeForceL(0), BeforeForceR(0), AfterForceL(0), AfterForceR(0),
          ForceSum(0), Power(0.0), Mileage(0), BkPoint(0), CtrlType(0), OutDesV(0.0), CtrlDes(0.0),
          SampPointNo(0), Timestamp(0)
    {
    }
    void StructInit()
    {
        Speed = 0.0;
        AddSpeed = 0.0;
        BeforeForceL = 0;
        BeforeForceR = 0;
        AfterForceL = 0;
        AfterForceR = 0;
        ForceSum = 0;
        Power = 0.0;
        Mileage = 0;
        BkPoint = 0;
        CtrlType = 0;
        OutDesV = 0.0;
        CtrlDes = 0.0;
        SampPointNo = 0;
        Timestamp = 0;
    };
    _SamplingDataItem(const _SamplingDataItem& sdi)
    {
        this->Speed = sdi.Speed;
        this->AddSpeed = sdi.AddSpeed;
        this->BeforeForceL = sdi.BeforeForceL;
        this->BeforeForceR = sdi.BeforeForceR;
        this->AfterForceL = sdi.AfterForceL;
        this->AfterForceR = sdi.AfterForceR;
        this->ForceSum = sdi.ForceSum;
        this->Power = sdi.Power;
        this->Mileage = sdi.Mileage;
        this->BkPoint = sdi.BkPoint;
        this->CtrlType = sdi.CtrlType;
        this->OutDesV = sdi.OutDesV;
        this->CtrlDes = sdi.CtrlDes;
        this->SampPointNo = sdi.SampPointNo;
        this->Timestamp = sdi.Timestamp;
    }
    _SamplingDataItem& operator =(const _SamplingDataItem& sdi){
       if(&sdi == this)
           return *this;
       this->Speed = sdi.Speed;
       this->AddSpeed = sdi.AddSpeed;
       this->BeforeForceL = sdi.BeforeForceL;
       this->BeforeForceR = sdi.BeforeForceR;
       this->AfterForceL = sdi.AfterForceL;
       this->AfterForceR = sdi.AfterForceR;
       this->ForceSum = sdi.ForceSum;
       this->Power = sdi.Power;
       this->Mileage = sdi.Mileage;
       this->BkPoint = sdi.BkPoint;
       this->CtrlType = sdi.CtrlType;
       this->OutDesV = sdi.OutDesV;
       this->CtrlDes = sdi.CtrlDes;
       this->SampPointNo = sdi.SampPointNo;
       this->Timestamp = sdi.Timestamp;
       return *this;
    }
//private:
//    Q_DISABLE_COPY(_SampDataItem)
}SamplingDataItem;

namespace Ui {
class MyPlotFrame;
}

class MyPlotFrame : public QWidget
{
    Q_OBJECT

public:
    explicit MyPlotFrame(QWidget *parent = nullptr);
    ~MyPlotFrame();

private:
    Ui::MyPlotFrame *ui;
    /// 曲线计数
    int X = 0;
    /// 曲线 放大缩小次数
    int zoomNum = 0;
    ///缩放标志
    bool isZoom = false;
    /// 十字线颜色
    QColor crossHairColor;
    /// 扭力及反扭，速度比例关系
    float ratio = 1.0f;
    /// 创建QMap实例  曲线图例数组 , 第一个参数为QString类型的键，第二个参数为int类型的值
    QMap<QString, int> legendMap;
    /// 创建QMap实例  曲线图例数组 , 第一个参数为QString类型的键，第二个参数为int类型的值
    QMap<int, QCPLayoutElement *> legendElementMap;
    QVector<double> lineCurve[EndC+1];
    /// 创建QMap实例  菜单
    QMap<QString, int> menuMap;
    /// 曲线图标数组
    QCPGraph *curveGraphs[EndC];
    /// 曲线菜单
    QMenu *menu;
    /// 曲线菜单Action数组
    QAction* menuActions[EndC];
    QAction *actionSpeedC;
    QAction *actionForceSumC;
    QAction *actionForceL0C;
    QAction *actionForceR0C;
    QAction *actionForceL1C;
    QAction *actionForceR1C;
    QAction *actionPowerC;
    QAction *actionOutVC;
    QAction *actionDesForceC;
    QAction *actionPIDBkPointC;
    QAction *actionJSDC;
    /// 全选
    QAction *actionAllMenu;

    /// 项目测试前初始化曲线
    void Init();


private slots:
    /// 选中图例，对应的曲线也选中
    void SelectionChanged();
    /// 曲线菜单函数
    void CheckedAction();

public slots:
    /// 项目测试前初始化曲线
    void InitCurve();
    /// 设置默认显示曲线
    void HideAllCurve();
    /// 设置默认显示曲线
    void SetVisible(CurveTypeEnum curveTypeIndex);
    /// 画曲线
    void DrawLine(QList<SamplingDataItem>& curveData);
};

#endif // MYPLOTFRAME_H
